﻿/*=============================================================================
* File Name : Matrix3.h                         Ver : 1.00  Date : 2009-3-30
*
* Description :
*
*       ３行３列座標変換行列計算　ヘッダ
*
* Author : 土田　悠貴.
*============================================================================*/
#ifndef _MATRIX3_H_
#define _MATRIX3_H_

namespace tglib
{

// 前方参照
class Vector2;
class Vector3;
class Quaternion;
class Plane;
class Matrix4;

/**
 * @brief 3行3列の行列計算クラス.
 */
class Matrix3
{
public:
	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 */
	Matrix3();

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in]     m11～m33　行列の各成分．
	 */
	Matrix3( float m11, float m12, float m13, 
			 float m21, float m22, float m23,
			 float m31, float m32, float m33 );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in]     axisX　X軸の成分．
	 * @param [in]     axisY　Y軸の成分．
	 * @param [in]     axisZ　Z軸の成分．
	 */
	Matrix3( 
		const Vector3& axisX,
		const Vector3& axisY,
		const Vector3& axisZ );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in]    p　行列の各成分．
	 */
	Matrix3( const float* p );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in]    M　4行4列構造体．
	 */
	Matrix3( const Matrix4& M );

	/*===========================================================================*/
	/**
	 * コンストラクタ．
	 *
	 * @param [in]    q　クォータニオン．
	 */
	Matrix3( const Quaternion& q );

	/*===========================================================================*/
	/**
	 * 単位行列化する．
	 *
	 * @return   求めた単位行列 ．
	 */
	Matrix3& identity();

	/*===========================================================================*/
	/**
	 * 拡大縮小行列を乗算．
	 *
	 * @param [in]     x x成分 ．
	 * @param [in]     y y成分 ．
	 * @param [in]     z z成分 ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& scale( float x, float y, float z );

	/*===========================================================================*/
	/**
	 * 拡大縮小行列を乗算．
	 *
	 * @param [in]     scaleFactor xyz成分 ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& scale( const Vector3& scaleFactor );

	/*===========================================================================*/
	/**
	 * 拡大縮小行列を乗算．
	 *
	 * @param [in]     scaleFactor xyz成分 ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& sclae( float scaleFactor );

	/*===========================================================================*/
	/**
	 * 回転行列を乗算．
	 *
	 * @param [in]     angle 回転角度 ．
	 * @param [in]     axisX ｘ軸成分．
	 * @param [in]     axisY ｙ軸成分 ．
	 * @param [in]     axisZ ｚ軸成分 ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotate( float angle, float axisX, float axisY, float axisZ );

	/*===========================================================================*/
	/**
	 * 回転行列を乗算．
	 *
	 * @param [in]     angle 回転角度 ．
	 * @param [in]     axis xyz軸成分．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotate( float angle, const Vector3& axis );

	/*===========================================================================*/
	/**
	 * 回転行列を乗算．
	 *
	 * @param [in]     q クォータニオン ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotate( const Quaternion& q );

	/*===========================================================================*/
	/**
	 * x軸の回転行列を乗算．
	 *
	 * @param [in]     x 角度．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotateX( float angle );

	/*===========================================================================*/
	/**
	 * y軸の回転行列を乗算．
	 *
	 * @param [in]     y 角度 ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotateY( float angle );

	/*===========================================================================*/
	/**
	 * z軸の回転行列を乗算．
	 *
	 * @param [in]     z 角度 ．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotateZ( float angle );

	/*===========================================================================*/
	/**
	 * ヨー、ピッチ、ロールの回転行列を乗算．
	 *
	 * @param [in]     yaw   ヨー．
	 * @param [in]     pitch ピッチ．
	 * @param [in]     roll  ロール．
	 * @return   乗算した行列 ．
	 */
	Matrix3& rotateYawPitchRoll( float yaw, float pitch, float roll );

	/*===========================================================================*/
	/**
	 * 平行移動を乗算．
	 *
	 * @param [in]     x x座標．
	 * @param [in]     y y座標．
	 * @return   乗算した行列 ．
	 */
	Matrix3& translate( float x, float y );

	/*===========================================================================*/
	/**
	 * 平行移動を乗算．
	 *
	 * @param [in]     translation 二次元座標．
	 * @return   乗算した行列 ．
	 */
	Matrix3& translate( const Vector2& translation );

	/*===========================================================================*/
	/**
	 * 逆行列にする．
	 *
	 * @return   変換した行列 ．
	 */
	Matrix3& inverse();

	/*===========================================================================*/
	/**
	 * 転置行列にする．
	 *
	 * @return   変換した行列 ．
	 */
	Matrix3& transpose();

	/*===========================================================================*/
	/**
	 * 転置逆行列にする．
	 *
	 * @return   変換した行列 ．
	 */
	Matrix3& inverseTranspose();

	/*===========================================================================*/
	/**
	 * 逆行列を取得する．
	 *
	 * @return   逆行列．
	 */
	Matrix3 getInverse() const;

	/*===========================================================================*/
	/**
	 * 転置行列を取得する．
	 *
	 * @return   転置行列．
	 */
	Matrix3 getTranspose() const;

	/*===========================================================================*/
	/**
	 * 転置逆行列を取得する．
	 *
	 * @return   転置逆行列．
	 */
	Matrix3 getInverseTranspose() const;

	/*===========================================================================*/
	/**
	 * スケール値の設定．
	 *
	 * @param [in]     x x成分 ．
	 * @param [in]     y y成分 ．
	 * @param [in]     z z成分 ．
	 * @return   設定した行列 ．
	 */
	Matrix3& setScale( float x, float y, float z );

	/*===========================================================================*/
	/**
	 * スケール値の設定．
	 *
	 * @param [in]     scaleFactor xyz成分 ．
	 * @return   設定した行列 ．
	 */
	Matrix3& setScale( const Vector3& scaleFactor );
	
	/*===========================================================================*/
	/**
	 * スケール値の設定．
	 *
	 * @param [in]     scaleFactor xyz成分 ．
	 * @return   設定した行列 ．
	 */
	Matrix3& setScale( float scaleFactor );

	/*===========================================================================*/
	/**
	 * 回転行列の設定．
	 *
	 * @param [in]     angle 角度．
	 * @param [in]     axisX x軸 ．
	 * @param [in]     axisY y軸 ．
	 * @param [in]     axisZ z軸 ．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotation( float angle, float axisX, float axisY, float axisZ );
	
	/*===========================================================================*/
	/**
	 * 回転行列の設定．
	 *
	 * @param [in]     angle 角度．
	 * @param [in]     axis  xyz軸 ．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotation( float angle, const Vector3& axis );
	
	/*===========================================================================*/
	/**
	 * 回転行列の設定．
	 *
	 * @param [in]     q クォータニオン．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotation( const Quaternion& q );

	/*===========================================================================*/
	/**
	 * X軸の回転行列の設定．
	 *
	 * @param [in]     angle 角度．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotationX( float angle );

	/*===========================================================================*/
	/**
	 * Y軸の回転行列の設定．
	 *
	 * @param [in]     angle 角度．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotationY( float angle );

	/*===========================================================================*/
	/**
	 * Z軸の回転行列の設定．
	 *
	 * @param [in]     angle 角度．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotationZ( float angle );

	/*===========================================================================*/
	/**
	 * ロール、ピッチ、ヨーから回転行列の設定．
	 *
	 * @param [in]     angle 角度．
	 * @param [in]     angle 角度．
	 * @param [in]     angle 角度．
	 * @return   設定した行列 ．
	 */
	Matrix3& setRotationYawPitchRoll( float yaw, float pitch, float roll );

	/*===========================================================================*/
	/**
	 * 平行移動量の設定．
	 *
	 * @param [in]     x x座標．
	 * @param [in]     y y座標．
	 * @return   設定した行列 ．
	 */
	Matrix3& setTranslation( float x, float y );

	/*===========================================================================*/
	/**
	 * 平行移動量の設定．
	 *
	 * @param [in]     translation 二次元座標．
	 * @return   設定した行列 ．
	 */
	Matrix3& setTranslation( const Vector2 translation );

	/*===========================================================================*/
	/**
	 * 座標変換．
	 *
	 * @param [in]     v 二次元座標．
	 * @return   変換した二次元座標．
	 */
	Vector2 transform( const Vector2& v ) const;

	/*===========================================================================*/
	/**
	 * 座標変換．
	 *
	 * @param [in]     v 二次元座標．
	 * @return   変換した二次元座標．
	 */
	Vector2 transformNormal( const Vector2& v ) const;

	/*===========================================================================*/
	/**
	 * 軸、位置の設定．
	 *
	 * @param [in]     axisX x軸の位置．
	 * @return   設定した行列．
	 */
	Matrix3& setAxisX( const Vector3& axisX );

	/*===========================================================================*/
	/**
	 * 軸、位置の設定．
	 *
	 * @param [in]     axisY y軸の位置．
	 * @return   設定した行列．
	 */
	Matrix3& setAxisY( const Vector3& axisY );
	
	/*===========================================================================*/
	/**
	 * 軸、位置の設定．
	 *
	 * @param [in]     axisZ z軸の位置．
	 * @return   設定した行列．
	 */
	Matrix3& setAxisZ( const Vector3& axisZ );

	/*===========================================================================*/
	/**
	 * ロールの取得．
	 *
	 * @return   ロール．
	 */
	float getRoll() const;

	/*===========================================================================*/
	/**
	 * ピッチの取得．
	 *
	 * @return   ピッチ．
	 */
	float getPitch() const;

	/*===========================================================================*/
	/**
	 * ヨーの取得．
	 *
	 * @return   ヨー．
	 */
	float getYaw() const;

	/*===========================================================================*/
	/**
	 * クォータニオンを取得．
	 *
	 * @return   クォータニオン．
	 */
	Quaternion getQuaternion() const;

	/*===========================================================================*/
	/**
	 * 軸、位置の取得．
	 *
	 * @return   X軸．
	 */
	Vector3 getAxisX() const;
	
	/*===========================================================================*/
	/**
	 * 軸、位置の取得．
	 *
	 * @return   Y軸．
	 */
	Vector3 getAxisY() const;

	/*===========================================================================*/
	/**
	 * 軸、位置の取得．
	 *
	 * @return   Z軸．
	 */
	Vector3 getAxisZ() const;

	/*===========================================================================*/
	/**
	 * (float*型)キャスト演算子オーバーロード．
	 *
	 * @return   型変換をした行列成分．
	 */
	operator float* ();

	/*===========================================================================*/
	/**
	 * (const flost*型)キャスト演算子オーバーロード．
	 *
	 * @return   型変換をした行列成分．
	 */
	operator const float* ();

	/*===========================================================================*/
	/**
	 * (+)単項演算子オーバーロード．
	 *
	 * @return 結果のMatrix3．
	 */
	Matrix3 operator + () const;

	/*===========================================================================*/
	/**
	 * (-)単項演算子オーバーロード．
	 *
	 * @return 結果のMatrix3.
	 */
	Matrix3 operator - () const;

	/*===========================================================================*/
	/**
	 * (+=) 演算子オーバーロード．
	 * 
	 * @param [in]  M Matrix3．
	 * @return 結果のMatrix3．
	 */
	Matrix3& operator += ( const Matrix3& M );

	/*===========================================================================*/
	/**
	 * (-=) 演算子オーバーロード．
	 * 
	 * @param [in]  M Matrix3．
	 * @return 結果のMatrix3．
	 */
	Matrix3& operator -= ( const Matrix3& M );

	/*===========================================================================*/
	/**
	 * (*=) 演算子オーバーロード．
	 * 
	 * @param [in]  M Matrix3．
	 * @return 結果のMatrix3．．
	 */
	Matrix3& operator *= ( const Matrix3& M );

	/*===========================================================================*/
	/**
	 * (*=) 演算子オーバーロード．
	 * 
	 * @param [in]  s スカラー．
	 * @return 結果のMatrix3．
	 */
	Matrix3& operator *= ( float s );

	/*===========================================================================*/
	/**
	 * (/=)演算子オーバーロード．
	 * 
	 * @param [in]  s スカラー．
	 * @return 結果のMatrix3．
	 */
	Matrix3& operator /= ( float s );


public:
	/** @brief 行列成分 */
	float m[3][3];
};

/***  以下非メンバ関数 *******************************************************/


/*===========================================================================*/
/**
 * (+)演算子オーバーロード．
 * 
 * @param [in]  m1 Matrix3．
 * @param [in]  m2 Matrix3．
 * @return 結果のMatrix3．
 */
const Matrix3 operator + ( const Matrix3& m1, const Matrix3& m2 );

/*===========================================================================*/
/**
 * (-)演算子オーバーロード．
 * 
 * @param [in]  m1 Matrix3．
 * @param [in]  m2 Matrix3．
 * @return 結果のMatrix3．
 */
const Matrix3 operator - ( const Matrix3& m1, const Matrix3& m2 );

/*===========================================================================*/
/**
 * (*)演算子オーバーロード．
 * 
 * @param [in]  m1 Matrix3．
 * @param [in]  m2 Matrix3．
 * @return 結果のMatrix3．
 */
const Matrix3 operator * ( const Matrix3& m1, const Matrix3& m2 );

/*===========================================================================*/
/**
 * (*) 演算子オーバーロード．
 * 
 * @param [in]  M Matrix3．
 * @param [in]  s スカラー．
 * @return 結果のMatrix3．
 */
const Matrix3 operator * ( const Matrix3& M, const float s );

/*===========================================================================*/
/**
 * (*) 演算子オーバーロード．
 * 
 * @param [in]  s スカラー．
 * @param [in]  M Matrix3．
 * @return 結果のMatrix3．
 */
const Matrix3 operator * ( const float s, const Matrix3& M );

/*===========================================================================*/
/**
 * (/) 演算子オーバーロード．
 * 
 * @param [in]  M Matrix3．
 * @param [in]  s スカラー．
 * @return 結果のMatrix3．
 */
const Matrix3 operator / ( const Matrix3& M, const float s );

/*===========================================================================*/
/**
 * (==) 演算子オーバーロード．
 * 
 * @param [in]  m1 Matrix3．
 * @param [in]  m2 Matrix3．
 * @return 比較結果．
 */
bool operator == ( const Matrix3& m1, const Matrix3& m2 );

/*===========================================================================*/
/**
 * (!=) 演算子オーバーロード．
 * 
 * @param [in]  m1 Matrix3．
 * @param [in]  m2 Matrix3．
 * @return 比較結果．
 */
bool operator != ( const Matrix3& m1, const Matrix3& m2 );

} // namespace tglib

#endif

/********** End of File ******************************************************/
